package com.cherry.system.service.impl;

import com.cherry.common.constant.MajorConstants;
import com.cherry.common.constant.UserConstants;
import com.cherry.common.core.domain.Ztree;
import com.cherry.common.core.domain.entity.SysMajor;
import com.cherry.common.core.text.Convert;
import com.cherry.common.exception.ServiceException;
import com.cherry.common.utils.StringUtils;
import com.cherry.system.mapper.SysMajorMapper;
import com.cherry.system.service.ISysMajorService;
import com.cherry.system.service.ISysUserService;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 专业管理 服务实现
 *
 * @author 孙晨阳
 */
@Service
public class SysMajorServiceImpl implements ISysMajorService {

    @Resource
    private SysMajorMapper majorMapper;

    @Resource
    private ISysUserService sysUserService;

    /**
     * 根据专业名称查询专业信息
     *
     * @param majorName 专业名称
     * @return 结果
     */
    @Override
    public SysMajor selectMajorByName(String majorName) {
        return majorMapper.selectMajorByName(majorName);
    }

    /**
     * 查询专业管理数据
     *
     * @param major 专业信息
     * @return 专业信息集合
     */
    @Override
    public List<SysMajor> selectMajorList(SysMajor major) {
        List<SysMajor> majorList = majorMapper.selectMajorList(major);

        majorList.forEach(majorSingle -> {

            // 如果是专业，直接获取各个专业的人数
            if (majorSingle.getAncestors().split(MajorConstants.SPLIT_COMMA).length == MajorConstants.ANCESTORS_THREE) {
                majorSingle.setMemberCount(sysUserService.selectUserCountByMajorId(majorSingle.getMajorId()));
            }

            // 如果是学院，获取学院的各个专业，然后再获取各个专业的人数
            if (majorSingle.getAncestors().split(MajorConstants.SPLIT_COMMA).length == MajorConstants.ANCESTORS_TWO) {
                List<SysMajor> majorChildren = majorMapper.selectChildrenMajorById(majorSingle.getMajorId());

                int collegeUserCount = majorChildren.stream().mapToInt(majorChild -> sysUserService.selectUserCountByMajorId(majorChild.getMajorId())).sum();

                majorSingle.setMemberCount(collegeUserCount);
            }

            // 如果是学校，获取学校的各个专业，排除学院，通过所有专业的人数相加获得学校人数
            if (majorSingle.getAncestors().split(MajorConstants.SPLIT_COMMA).length == MajorConstants.ANCESTORS_ONE) {

                List<SysMajor> majorChildren = majorMapper.selectChildrenMajorById(majorSingle.getMajorId());

                int schoolUserCount = majorChildren.stream().filter(majorChild -> majorChild.getAncestors().split(MajorConstants.SPLIT_COMMA).length == MajorConstants.ANCESTORS_THREE)
                        .mapToInt(majorChild -> sysUserService.selectUserCountByMajorId(majorChild.getMajorId())).sum();

                majorSingle.setMemberCount(schoolUserCount);
            }
        });

        return majorList;
    }

    /**
     * 查询专业管理树
     *
     * @param major 专业信息
     * @return 所有专业信息
     */
    @Override
    public List<Ztree> selectMajorTree(SysMajor major) {
        List<SysMajor> majorList = majorMapper.selectMajorList(major);
        return initZtree(majorList);
    }

    /**
     * 根据专业ID查询信息
     *
     * @param majorId 专业ID
     * @return 专业信息
     */
    @Override
    public SysMajor selectMajorById(Long majorId) {
        return majorMapper.selectMajorById(majorId);
    }

    /**
     * 查询专业管理树（排除下级）
     *
     * @param major 专业信息
     * @return 所有专业信息
     */
    @Override
    public List<Ztree> selectMajorTreeExcludeChild(SysMajor major) {
        Long excludeId = major.getExcludeId();
        List<SysMajor> majors = majorMapper.selectMajorList(major);
        if (excludeId.intValue() > 0) {
            majors.removeIf(m -> m.getMajorId().intValue() == excludeId || ArrayUtils.contains(StringUtils.split(m.getAncestors(), ","), excludeId + ""));
        }
        return initZtree(majors);
    }

    /**
     * 校验专业名称是否唯一
     *
     * @param major 专业信息
     * @return 结果
     */
    @Override
    public String checkMajorNameUnique(SysMajor major) {
        Long majorId = StringUtils.isNull(major.getMajorId()) ? -1L : major.getMajorId();
        SysMajor info = majorMapper.checkMajorNameUnique(major.getMajorName(), major.getParentId());
        if (StringUtils.isNotNull(info) && info.getMajorId().longValue() != majorId.longValue()) {
            return UserConstants.MAJOR_NAME_NOT_UNIQUE;
        }
        return UserConstants.MAJOR_NAME_UNIQUE;
    }

    /**
     * 新增专业信息
     *
     * @param major 专业信息
     * @return 结果
     */
    @Override
    public int insertMajor(SysMajor major) {
        SysMajor info = majorMapper.selectMajorById(major.getParentId());
        if (!UserConstants.MAJOR_NORMAL.equals(info.getStatus())) {
            throw new ServiceException("部门停用，不允许新增");
        }
        major.setAncestors(info.getAncestors() + "," + major.getParentId());
        return majorMapper.insertMajor(major);
    }

    /**
     * 根据ID查询所有子专业（学院）（正常状态）
     *
     * @param majorId 专业（学院）ID
     * @return 结果
     */
    @Override
    public int selectNormalChildrenMajorById(Long majorId) {
        return majorMapper.selectNormalChildrenMajorById(majorId);
    }

    /**
     * 修改保存专业（学院）信息
     *
     * @param major 专业信息
     * @return 结果
     */
    @Override
    public int updateMajor(SysMajor major) {
        SysMajor newParentMajor = majorMapper.selectMajorById(major.getParentId());
        SysMajor oldMajor = majorMapper.selectMajorById(major.getMajorId());
        if (StringUtils.isNotNull(newParentMajor) && StringUtils.isNotNull(oldMajor)) {
            String newAncestors = newParentMajor.getAncestors() + "," + newParentMajor.getMajorId();
            String oldAncestors = oldMajor.getAncestors();
            major.setAncestors(newAncestors);
            updateMajorChildren(major.getMajorId(), newAncestors, oldAncestors);
        }
        int result = majorMapper.updateMajor(major);
        if (UserConstants.MAJOR_NORMAL.equals(major.getStatus()) && StringUtils.isNotEmpty(major.getAncestors())
                && !StringUtils.equals("0", major.getAncestors())) {
            // 如果该部门是启用状态，则启用该部门的所有上级部门
            updateParentMajorStatusNormal(major);
        }
        return result;
    }

    /**
     * 根据父部门ID查询下级部门数量
     *
     * @param parentId 父部门ID
     * @return 结果
     */
    @Override
    public int selectMajorCount(Long parentId) {
        SysMajor major = new SysMajor();
        major.setParentId(parentId);
        return majorMapper.selectMajorCount(major);
    }

    /**
     * 查询学院或专业是否存在用户
     *
     * @param majorId 学院或专业ID
     * @return 结果
     */
    @Override
    public boolean checkMajorExistUser(Long majorId) {
        int result = majorMapper.checkMajorExistUser(majorId);
        return result > 0;
    }

    /**
     * 删除学院或专业
     *
     * @param majorId 学院或专业ID
     * @return 结果
     */
    @Override
    public int deleteMajorById(Long majorId) {
        return majorMapper.deleteMajorById(majorId);
    }

    /**
     * 专业状态修改
     *
     * @param major 专业信息
     * @return 结果
     */
    @Override
    public int changeStatus(SysMajor major) {
        return majorMapper.updateMajor(major);
    }

    /**
     * 修改该专业的的父级专业状态
     *
     * @param major 当前专业
     */
    private void updateParentMajorStatusNormal(SysMajor major) {
        String ancestors = major.getAncestors();
        Long[] majorIds = Convert.toLongArray(ancestors);
        majorMapper.updateMajorStatusNormal(majorIds);
    }

    /**
     * 修改子元素关系
     *
     * @param majorId      被修改的专业ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    private void updateMajorChildren(Long majorId, String newAncestors, String oldAncestors) {
        List<SysMajor> children = majorMapper.selectChildrenMajorById(majorId);
        children.forEach(child -> child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors)));
        if (!children.isEmpty()) {
            majorMapper.updateMajorChildren(children);
        }
    }

    /**
     * 对象转专业树
     *
     * @param majorList 专业列表
     * @return 树结构列表
     */
    private List<Ztree> initZtree(List<SysMajor> majorList) {
        return initZtree(majorList, null);
    }

    /**
     * 对象转专业树
     *
     * @param majorList    专业列表
     * @param roleDeptList 角色已存在菜单列表
     * @return 树结构列表
     */
    private List<Ztree> initZtree(List<SysMajor> majorList, List<String> roleDeptList) {
        List<Ztree> ztrees = new ArrayList<>();
        boolean isCheck = StringUtils.isNotNull(roleDeptList);

        majorList.forEach(major -> {
            if (UserConstants.MAJOR_NORMAL.equals(major.getStatus())) {
                Ztree ztree = new Ztree();
                ztree.setId(major.getMajorId());
                ztree.setpId(major.getParentId());
                ztree.setName(major.getMajorName());
                ztree.setTitle(major.getMajorName());
                if (isCheck) {
                    ztree.setChecked(roleDeptList.contains(major.getMajorId() + major.getMajorName()));
                }
                ztrees.add(ztree);
            }
        });
        return ztrees;
    }
}
